package com.witsight.cassandra.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.data.cassandra.convert.CassandraConverter;
import org.springframework.data.cassandra.core.CassandraAdminOperations;
import org.springframework.data.cassandra.core.CassandraTemplate;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
import com.witsight.cassandra.bean.CassandraMappings;
import com.witsight.cassandra.dao.NameQueriesRepository;
import com.witsight.cassandra.dao.impl.PageCassandraTemplate;
import com.witsight.cassandra.util.CqlBuilder;
import com.witsight.platform.model.BoEntity;
import com.witsight.platform.util.io.FileNameUtil;
import com.witsight.platform.util.io.XMLUtil;
import com.witsight.platform.util.lang.CollectionUtil;
import com.witsight.platform.util.lang.ObjectUtil;
import com.witsight.platform.util.lang.StringUtil;

/**   
 * 说明：Cassandra 自动配置 
 * @Title: CassandraAutoConfig.java 
 * @Package com.witsight.cassandra.config 
 * @See: {@link #CassandraAutoConfiguration()}
 * Copyright: Copyright (c) 2017
 * Company:sany huax witsight team by product
 * @author: penght  
 * @date: 2017年9月21日 上午10:14:20 
 * @version: V1.0
 *
 */
@Configuration
@EnableConfigurationProperties({ CassandraCustomProperties.class })
@ConditionalOnClass({ Cluster.class, CassandraAdminOperations.class })
public class CassandraAutoConfiguration {
	/**
	 * 说明：定义后能再同一类中使用static常量log
	 */
	private static final Logger log = LoggerFactory.getLogger(CassandraAutoConfiguration.class);
	/**
	 * 
	 * 说明：创建cassandra配置的仓库
	 * @Title: cassandraQueryRepository
	 * @See: {@link #cassandraQueryRepository(CassandraCustomProperties)}
	 * @author penght
	 * @param cassandraProperties Cassandra属性
	 * @return CassandraQueryRepository
	 * @throws Exception 
	 * @date: 2017年9月21日 上午10:56:58
	 */
	@Bean
	@ConditionalOnMissingBean
	public NameQueriesRepository cassandraQueryRepository(CassandraCustomProperties cassandraProperties) throws Exception {
		BoEntity configMappings = loadCassandraConfig(cassandraProperties);		
		return new NameQueriesRepository(configMappings);
	}
	
	/** 说明：加载全部的Cassandra配置文件
	 * 
	 * @Title: loadCassandraConfig
	 * @See: {@link #loadCassandraConfig()}
	 * @author penght
	 * @date: 2016年9月22日 下午2:23:26
	 * @exception Exception
	 *                处理异常
	 */
	private BoEntity loadCassandraConfig(CassandraCustomProperties cassandraProperties) throws Exception {
		BoEntity configs = new BoEntity("CassandraConfig");
		if (ObjectUtil.isEmpty(cassandraProperties.getSqlConfigs())) {
			return configs;
		}
		
		for (Resource resource : cassandraProperties.getSqlConfigs()) {
			if (log.isDebugEnabled()) {
				log.debug("cassandra config file name : {}", resource.getFilename());
			}
			String beanName = FileNameUtil.getBaseName(resource.getFilename());
			CassandraMappings cassandraMappings = XMLUtil.xml2Bean(resource.getInputStream(), CassandraMappings.class);
			setConfigs(configs, cassandraMappings ,beanName);
		}
		
		return configs;
	}
	
	private void setConfigs(final BoEntity configs,final CassandraMappings cassandraMappings,final String beanName) {
		if (cassandraMappings == null || CollectionUtil.isEmpty(cassandraMappings.getNameQuerys())) {
			return;
		}
		
		cassandraMappings.getNameQuerys().forEach(nameQuery-> {
			String key = StringUtil.upperCase((beanName + "." + nameQuery.getName()));
			if (configs.containsKey(key)) {
				throw new IllegalArgumentException("The same key is configured. key :" + key);
			} else {
				// 替换表名称
				String query = CqlBuilder.getQueryString(nameQuery.getQuery(), cassandraMappings.getTable());
				nameQuery.setQuery(query);
				configs.set(key, nameQuery);
			}
		});
	}
	
	@Bean("pageCassandraTemplate")
	@ConditionalOnMissingBean
	public CassandraTemplate cassandraTemplate(Session session,
			CassandraConverter converter) throws Exception {
		return new PageCassandraTemplate(session, converter);
	}
}
